/**
 * @author 艾尼亚尔
 * @date 2025/8/7
 * @description
 */
import {defineStore} from "pinia";
import {
    getTokenTime,
    setLocalStorage,
    setToken,
    setTokenTime,
    getLocalStorage,
    removeToken,
    removeLocalStorage,
    removeTokenTime
} from '@/utils/storage.ts'
import {postRequest, putRequest} from "@/api";
import {UseAppStore} from '@/stores/app.ts';
import type {RouteRecordRaw} from "vue-router";
import {store} from "@/stores/index.ts";


interface UserState {
    nickname: string;
    account: string;
    avatar: string| null;
    messageCount: number;
    refreshPromise: boolean; //无感刷新并发锁
}

interface LoginData {
    id: string;
    token: string;
    expire_time: number;
    account: string;
    nickname?: string;
    avatar?: string|null;
    menus: RouteRecordRaw[] | [];
    authorities: string[];
}

interface RefreshTokenResponse {
    token: string;
    expire_time: number;
}

export const userStore = defineStore('user', {
    state: (): UserState => {
        return {
            nickname: getLocalStorage('nickname') as string || '',
            avatar: getLocalStorage('avatar') as string || null,
            account: getLocalStorage('account') as string || '',
            messageCount: 0,
            refreshPromise: false,//
        }
    },
    actions: {
        /**
         * 设置token
         * @param token
         * @param time
         */
        setToken(token: string, time: number) {
            setToken(token, time)
            setTokenTime(time);
        },
        /**
         * 设置用户账号
         * @param account
         */
        setUserAccount(account: string) {
            this.account = account;
            setLocalStorage("account", account);
        },
        /**
         * 设置用户昵称
         * @param nickName
         */
        setNickName(nickName: string) {
            this.nickname = nickName;
            setLocalStorage("nickname", nickName);
        },
        /**
         * 设置用户头像
         * @param avatar
         */
        setAvatar(avatar: string|null) {
            this.avatar = avatar;
            setLocalStorage("avatar", avatar);
        },
        /**
         * 清空本地缓存
         */
        clearStorage() {
            removeToken();
            removeLocalStorage("tab_list");
            removeLocalStorage("account");
            removeLocalStorage("nickName");
            removeLocalStorage("avatar");
            removeLocalStorage("routers_list");
            removeLocalStorage("authorities");
            removeLocalStorage("UID");
            removeTokenTime();
            const appStore = UseAppStore();
            appStore.setDynamicAddedRoute(false)
            appStore.tabs = [];
        },
        //登录
        async login(params: Recordable) {
            return await postRequest('/login', params).then((response: ResponseResult) => {
                if (response.code == 200) {
                    const data: LoginData = response.data as LoginData;
                    this.setToken(data.token, data.expire_time);
                    this.setUserAccount(data.account);
                    this.setNickName(data.nickname ? data.nickname : '');
                    this.setAvatar(data.avatar ? data.avatar : '');
                    setLocalStorage("UID", data.id);
                    setLocalStorage("routers_list", data.menus);
                    setLocalStorage("authorities", data.authorities)
                    return response;
                }
                return Promise.reject(response);
            })
        },
        //退出登录
        async logout() {
            return await putRequest('/sett/logout').then((response: ResponseResult) => {
                this.clearStorage()
                return response;
            })
        },
        /**
         * 无感刷新 token（带并发锁）
         */
        refreshToken() {
            if (this.refreshPromise) return this.refreshPromise; // 并发锁
            this.refreshPromise = true;
            putRequest<ResponseResult<RefreshTokenResponse>>('/sett/refresh_token').then((response) => {
                if (response.code === 200 && response.data) {
                    const refreshData = (response as unknown as { data: RefreshTokenResponse }).data;
                    this.setToken(refreshData.token, refreshData.expire_time);
                }
            }).finally(() => {
                this.refreshPromise = false;
            });
        },
        /**
         * 判断 token 是否将在 expireMinutes 分钟内过期
         */
        willExpireSoon(expireMinutes = 10): boolean {
            const expire = Number(getTokenTime());
            if (!expire) return false;
            const remainMin = (expire - Date.now()) / 1000 / 60;
            return remainMin > 0 && remainMin < expireMinutes;
        }
    }
})

export function userStoreWidthOut() {
    return userStore(store);
}